package com.translate.web.service.impl;

import com.common.util.ListConvertMap;
import com.common.util.TheMagicSkillOfBeingInvisible;
import com.dao.base.IBaseMapper;
import com.translate.web.constant.RedisConstant;
import com.translate.web.dao.OrderDiscountInformationMapper;
import com.translate.entity.OrderDiscountInformation;
import com.param.contract.IIdParam;
import com.translate.web.param.contract.IOrderDiscountInformationAddParam;
import com.translate.web.service.IOrderDiscountInformationService;
import com.basic.service.impl.BaseServiceImpl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;

@Service
public class OrderDiscountInformationServiceImpl extends BaseServiceImpl<OrderDiscountInformation>
		implements IOrderDiscountInformationService {
	
	private RedisTemplate<String, List<OrderDiscountInformation>> redisTemplate;
	
	
	@Autowired
	public void setRedisTemplate(RedisTemplate<String, List<OrderDiscountInformation>> redisTemplate) {
		this.redisTemplate = redisTemplate;
	}

	public OrderDiscountInformationServiceImpl(OrderDiscountInformationMapper mapper) {
		super(mapper);
	}

	protected Class<OrderDiscountInformation> getEntityClass() {
		return OrderDiscountInformation.class;
	}

	
	
	
	@Override
	protected int getId(OrderDiscountInformation data) {
		return data.getId();
	}

	@Override
	public <S extends IOrderDiscountInformationAddParam> int batchInsert(List<S> list, int orderId, Map<Integer, BigDecimal> products, int createId, int belongPersonId) {

		List<OrderDiscountInformation> discountInformations = new ArrayList<>();
		
		OrderDiscountInformation discountInformation; 
		
		for (S s : list) {
			
			discountInformation = new OrderDiscountInformation();
			
			discountInformation.setDiscount(s.getDiscount());
			
			discountInformation.setNumber(s.getNumber());
			
			discountInformation.setOrderId(orderId);
			discountInformation.setProductId(s.getProductId());
			
			discountInformation.setCreateId(createId);
			
			discountInformation.setBelongingPerson((int) TheMagicSkillOfBeingInvisible.GetDecodeUserID(belongPersonId));
			
			discountInformation.setPrice(products.get(s.getProductId()));
			
			discountInformations.add(discountInformation);
		}
		
		return this.batchInsert(discountInformations);
	}
	
	
	protected <S> boolean compareMasterCondition(S condition, OrderDiscountInformation data) {

		IOrderDiscountInformationAddParam customerPoolAddMemberParam = (IOrderDiscountInformationAddParam) condition;

		Integer num = customerPoolAddMemberParam.getNumber();

		Float discount = customerPoolAddMemberParam.getDiscount();
		
		return 0 == discount.compareTo(data.getDiscount()) && 0 == num.compareTo(data.getNumber());
	}
	
	
	
	
	@Override
	protected OrderDiscountInformation getEntityInstance() {
		// TODO Auto-generated method stub
		return new OrderDiscountInformation();
	}

	@Override
	public <S> int updateOrderInfo(List<S> recive, Map<Integer, BigDecimal> products, int assocId, int userId, int belongPersonId) {

		IBaseMapper<OrderDiscountInformation> modulePicMapper = this.getBaseMapper();

		List<OrderDiscountInformation> assocData = modulePicMapper.getDataByAccessId(assocId);

		Function<S, Integer> function = (e) -> ((IIdParam) e).getId();

		Map<Integer, S> map = ListConvertMap.listToMap(recive, function);

		List<OrderDiscountInformation> updateList = new ArrayList<>();

		List<Integer> delList = new ArrayList<>();

		OrderDiscountInformation toUpdate = null;

		S obtainedFromTheMap;

		Integer id;

		for (OrderDiscountInformation t : assocData) {

			id = getId(t);

			obtainedFromTheMap = map.get(id);

			if (null != obtainedFromTheMap) { // 更新的
				
				// 在现有的图片里面可以找到

				// 比较 data名称是否一致
				if (compareMasterCondition(obtainedFromTheMap, t)) {
					continue;
				}

				toUpdate = getEntityInstance();

				toEntity(toUpdate, obtainedFromTheMap, products, assocId, userId, belongPersonId);

				updateList.add(toUpdate);
				
				continue;
			}

			// 删除（数据库）
			delList.add(id);

			// 删除(OSS)的
//			delThumbs.add(t.getPic());
		}
		OrderDiscountInformation toAdd;

		List<OrderDiscountInformation> addList = new ArrayList<>();

		IIdParam idParam;

		for (S t : recive) {

			idParam = (IIdParam) t;

			if (0 != idParam.getId().compareTo(0)) {
				continue;
			}

			toAdd = getEntityInstance();

			toEntity(toAdd, t, products, assocId, userId, belongPersonId);

			addList.add(toAdd);
		}

		if (0 != updateList.size()) {

			this.updateBatch(updateList, assocId);
		}

		if (0 != addList.size()) {
			this.batchInsert(addList);
		}

		if (0 != delList.size()) {
			this.delete(delList);
		}
		
		return 0;
	}

	
	protected <S> void toEntity(
			OrderDiscountInformation customerPoolMember, 
			S obtainedFromTheMap, 
			Map<Integer, BigDecimal> products, 
			int assocId, 
			int userId, 
			int belongPersonId
	) {

		IOrderDiscountInformationAddParam customerPoolAddMemberParam = (IOrderDiscountInformationAddParam) obtainedFromTheMap;

		customerPoolMember.setOrderId(assocId);

		Integer id = null;
		
		if (obtainedFromTheMap instanceof IIdParam) {
			id = ((IIdParam) obtainedFromTheMap).getId();
			
			if (null != id) {
				customerPoolMember.setId(id);
			}
		}

		customerPoolMember.setDiscount(customerPoolAddMemberParam.getDiscount());

		customerPoolMember.setPrice(products.get(customerPoolAddMemberParam.getProductId()));
		
		customerPoolMember.setNumber(customerPoolAddMemberParam.getNumber());
		
		customerPoolMember.setProductId(customerPoolAddMemberParam.getProductId());
		
		customerPoolMember.setCreateId(userId);
		
		customerPoolMember.setBelongingPerson(belongPersonId);
	}
	
	

	@Override
	public <S extends IOrderDiscountInformationAddParam> BigDecimal getTotalPrice(List<S> list,
			Map<Integer, BigDecimal> products) {
		
		BigDecimal b100 = new BigDecimal(100);
		
		BigDecimal totalPrice = new BigDecimal(0);
		
		BigDecimal currentPrice;
		
		for (S s : list) {
			
			currentPrice = products.get(s.getProductId());
			
			totalPrice = totalPrice.add(totalPrice.add(currentPrice.multiply(BigDecimal.valueOf(s.getDiscount())).multiply(BigDecimal.valueOf(s.getNumber())) .divide(b100)));
		}
		return totalPrice;
	}

	/**
	 * 获取
	 */
	@Override
	public List<OrderDiscountInformation> getOrderDiscount(int id, int belongingPersonId) {
		
		return this.getOrderDiscountToCache(id, belongingPersonId);
	}
	
	/**
	 * 折扣列表
	 * @param id
	 * @param belongingPersonId
	 * @return
	 */
	protected List<OrderDiscountInformation> getOrderDiscountToCache(int id, int belongingPersonId) {

		String key = RedisConstant.getOrderDiscounttKey(id);

		ValueOperations<String, List<OrderDiscountInformation>> valueOperations = this.redisTemplate.opsForValue();
		
		List<OrderDiscountInformation> discountInformations = valueOperations.get(key);
		
		if (null != discountInformations) {
			return discountInformations;
		}
		
		OrderDiscountInformationMapper discountInformationMapper = this.getBaseMapper();
		
		discountInformations = discountInformationMapper.getDiscountInformations(id, belongingPersonId);
		
		if (null == discountInformations) {
			discountInformations = new ArrayList<>(0);
			
			valueOperations.set(key, discountInformations, 3, TimeUnit.SECONDS);
			
			return discountInformations;
		}
		
		valueOperations.set(key, discountInformations, 12, TimeUnit.SECONDS);
		
		return discountInformations;
	}

	
}